Medium 好讀版點此。
分支管理是 git 的核心功能之一,不論是在本地端、或者跨機器協作,都可以讓我們在某個支線上進行開發或測試,而不影響主線。
本篇文章將在本地端的 git 倉儲創建分支,在分支上各自形成 commit 後,觀察合併分支時會發生的兩種狀況:「順利合併」與「合併衝突」。
在一個已經經過 git init 初始化的 git 倉儲中,透過以下指令建立 file.txt 文字檔案,內容為 "Initial content":
echo "Initial content" > file.txt
接著把這個新建的檔案先放到預存區:
git add file.txt
再建立第一個 commit:
git commit -m "Initial commit"
現在我們在 main 分支上已經有雜湊碼為 deb6e91... 的 commit:
現在我們以 git branch 指令,建立 featureA 分支:
git branch featureA
再用一樣的 git branch 指令,建立 featureB 分支:
git branch featureB
現在我們以 git branch 觀察,可發現目前有 main、featureA 與 featureB 三個分支:
main 分支打星號並顯示綠色,且右上角的藍色括弧也是寫 (main),表示我們現在在 main 分支上,可用下列指令切換到 featureA 分支:
git switch featureA
以 git branch 指令確認,發現變成 featureA 打星號且變綠色、最右邊的藍色括弧也變成 featureA,表示目前在 featureA 分支上:
同理,也能夠過以下指令,切換到 featureB 分支上:
git switch featureB
再以 git branch 檢查確認:
在合併分支前,我們先以 git switch 切換到 featureA 分支:
git switch featureA
接著在這個分支上建立一個名為 file.txt 的檔案,內容為 "Feature A work":
echo "Feature A work" > file.txt
把 file.txt 加到預存區:
git add file.txt
再為其建立一個 commit:
git commit -m "Add Feature A work"
這時透過 git log 觀察,可發現 805ba26... 這個 commit 只在 featureA 分支而不在 main 分支上:
現在我們要把 805ba26... 合併到 main 分支上。
首先切換到 main 分支:
git switch main
再用 git merge 指令合併:
git merge featureA
合併之後透過 git log 指令檢查,可發現在 main 分支與 featureA 分支都有 805ba26... 這個 commit,而 featureB 分支上依然只有 deb6e91... 這個舊的 commit:

現在我們切到 featureB 分支:
git switch featureB
在 featureB 分支上創建同樣名為 file.txt 檔案,但內容為 "Feature B conflicting line":
echo "Feature B conflicting line" > file.txt
一樣把這裡的 file.txt 放到預存區:
git add file.txt
再形成新的 commit:
git commit -m "Add conflicting change from featureB"
使用 git log 指令檢查,發現 featureB 分支有 339a1be... 與 deb6e91... 兩個 commit、featureA 與 main 分支則是剛剛看到的 805ba26... 與 deb6e91... 兩個 commit:

這時如果切回去 main 分支:
git switch main
再把 featureB 分支合併過來:
git merge featureB
會發生什麼事呢?
來看看終端機:

再來看看編輯器:

這種狀況稱為「合併衝突(merge conflict)」,源於合併時,兩個分支在同一檔案的同樣行別發生改變,這時有三種解決方式:
main)」的版本為準。featureB)」的版本為準。我們依照需求在編輯器點選其中一個之後,把 file.txt 放進預存區:
git add file.txt
再形成新 commit:
git commit -m "Merge featureB into main"
以 git log 檢查,可發現在 main 分支上多了一個代表把 featureB 分支合併進來的新 commit 9b7b77f...:

現在我們換個方式調整分支結構。
先輸入以下指令,退回合併前的狀態:
git reset --hard HEAD~1
接著切換到 featureB 分支上:
git switch featureB
然後把這個 featureB 分支「接」上 main 分支:
git rebase main
衝突再度發生,原因跟剛剛一樣,都是兩分支同樣在 file.txt 的同樣行別發生變化:
這次一樣會跑出 Accept Current Change、Accept Incoming Change、Accept Both Changes 三種選項,依照需求選擇一個之後,把檔案放進預存區:
git add file.txt
接著繼續做 rebase:
git rebase --continue
這時可能跳出 vim 之類的編輯器,要我們編輯 rebase 的 commit 訊息,編輯好訊息並關閉編輯器後,即完成 rebase:

之後我們會細看分支新增、刪除、轉換,還有合併衝突的處理,如果對於上述用上層指令操作仍不熟悉,可以先參考以下由高見龍老師撰寫的公開文章複習:
如果跳出 vim 編輯器不會處理,則可以參考:
以上層的瓷器指令要管理分支時,主要會用到以下指令:
git branch:用來新增與查看分支。git switch:切換分支,跟以前使用的 git checkout 相比,功能更為專一。git merge:合併分支。git rebase:「看似」把某分支基底接到另一分支上,可想成是另一種合併分支的方式。若在合併的兩分支同一檔案的相同區塊做出不一樣的更改,則在 git merge 與 git rebase 時會產生衝突,需要另外去解。